package models;

import play.db.jpa.JPA;

import javax.persistence.*;
import javax.persistence.criteria.*;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by xuyang on 2017/6/12.
 */
@Entity(name="public.\"TA001\"")
public class TA001 extends BeamModel {

    // 报文ID
    @Column(name = "\"MSG_ID\"")
    private String msg_id;

    // 网关时间
    @Column(name = "\"GATEWAY_TIME\"")
    private Date gateway_time;

    // 报文优先级
    @Column(name = "\"PRIORITY\"")
    private String priority;

    // 报文接收地址
    @Column(name = "\"RCV_ADDRESS\"")
    private String rcv_address;

    // 报文发送地址
    @Column(name = "\"SND_ADDRESS\"")
    private String snd_address;

    // BEP时间
    @Column(name = "\"BEP_TIME\"")
    private String bep_time;

    // SMI
    @Column(name = "\"SMI\"")
    private String smi;

    // 机尾号
    @Column(name = "\"AIRCRAFT_ID\"")
    private String aircraft_id;

    // 航班号
    @Column(name = "\"FLIGHT_ID\"")
    private String flight_id;

    // 服务商三字码
    @Column(name = "\"DSP\"")
    private String dsp;

    // RGS三字码
    @Column(name = "\"RGS\"")
    private String rgs;

    // RGS时间
    @Column(name = "\"RGS_TIME\"")
    private String rgs_time;

    //MSN
    @Column(name = "\"MSN\"")
    private String msn;

    //报文原文
    @Column(name = "\"RAW_MSG\"")
    private String raw_msg;

    // 是否是ADSC报文
    @Column(name = "\"IS_ADSC\"")
    private boolean is_adsc;

    //下行报拆分状态
    @Column(name="\"SPLIT_RESULT\"")
    private Integer split_result;

    @Transient
    private String freeText;

    @Transient
    public String getRawMsgFragment(int max) {
        if (getRaw_msg().length() > max) {
            return getRaw_msg().substring(0, max);
        }

        return getRaw_msg();
    }

    public String getMsg_id() {
        return msg_id;
    }

    public void setMsg_id(String msg_id) {
        this.msg_id = msg_id;
    }

    public Date getGateway_time() {
        return gateway_time;
    }

    public void setGateway_time(Date gateway_time) {
        this.gateway_time = gateway_time;
    }

    public String getPriority() {
        return priority;
    }

    public void setPriority(String priority) {
        this.priority = priority;
    }

    public String getRcv_address() {
        return rcv_address;
    }

    public void setRcv_address(String rcv_address) {
        this.rcv_address = rcv_address;
    }

    public String getSnd_address() {
        return snd_address;
    }

    public void setSnd_address(String snd_address) {
        this.snd_address = snd_address;
    }

    public String getBep_time() {
        return bep_time;
    }

    public void setBep_time(String bep_time) {
        this.bep_time = bep_time;
    }

    public String getSmi() {
        return smi;
    }

    public void setSmi(String smi) {
        this.smi = smi;
    }

    public String getAircraft_id() {
        return aircraft_id;
    }

    public void setAircraft_id(String aircraft_id) {
        this.aircraft_id = aircraft_id;
    }

    public String getFlight_id() {
        return flight_id;
    }

    public void setFlight_id(String flight_id) {
        this.flight_id = flight_id;
    }

    public String getDsp() {
        return dsp;
    }

    public void setDsp(String dsp) {
        this.dsp = dsp;
    }

    public String getRgs() {
        return rgs;
    }

    public void setRgs(String rgs) {
        this.rgs = rgs;
    }

    public String getRgs_time() {
        return rgs_time;
    }

    public void setRgs_time(String rgs_time) {
        this.rgs_time = rgs_time;
    }

    public String getMsn() {
        return msn;
    }

    public void setMsn(String msn) {
        this.msn = msn;
    }

    public String getRaw_msg() {
        return raw_msg;
    }

    public void setRaw_msg(String raw_msg) {
        this.raw_msg = raw_msg;
    }

    public boolean isIs_adsc() {
        return is_adsc;
    }

    public void setIs_adsc(boolean is_adsc) {
        this.is_adsc = is_adsc;
    }

    public Integer getSplit_result() {
        return split_result;
    }

    public void setSplit_result(Integer split_result) {
        this.split_result = split_result;
    }

    public String getFreeText() {
        return freeText;
    }

    public void setFreeText(String freeText) {
        this.freeText = freeText;
    }

    public static List<TA001> filterBy(Date dateStart, Date dateEnd, String aircraft, String smi, String flight_id, String contains, int limit) {
        EntityManager em = JPA.em();
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<TA001> query = cb.createQuery(TA001.class);
        Root<TA001> root = query.from(TA001.class);

        final List<Predicate> predicates = getPredicates(dateStart, dateEnd, aircraft, smi, flight_id, contains, cb, root);

        query.select(root);
        query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])))
                .orderBy(cb.desc(root.<String>get("gateway_time")));

        TypedQuery tQuery = em.createQuery(query);

        if (dateStart != null) {
            tQuery.setParameter("dateStart", dateStart);
        }
        if (dateEnd != null) {
            tQuery.setParameter("dateEnd", dateEnd);
        }

        if (limit > -1) {
            tQuery.setMaxResults(limit);
        }

        List<models.TA001> items = tQuery.getResultList();

        return items;
    }

    public static Long maxResultsFilterBy(Date dateStart, Date dateEnd, String aircraft, String smi, String flight_id, String contains) {
        EntityManager em = JPA.em();
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<Long> query = cb.createQuery(Long.class);
        Root<TA001> root = query.from(TA001.class);

        final List<Predicate> predicates = getPredicates(dateStart, dateEnd, aircraft, smi, flight_id, contains, cb, root);

        query.select(cb.count(root));
        query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));

        TypedQuery tQuery = em.createQuery(query);

        if (dateStart != null) {
            tQuery.setParameter("dateStart", dateStart);
        }
        if (dateEnd != null) {
            tQuery.setParameter("dateEnd", dateEnd);
        }

        Long count = (Long)tQuery.getSingleResult();

        return count;
    }

    private static List<Predicate> getPredicates(Date dateStart, Date dateEnd, String aircraft, String smi, String flight_id, String contains, CriteriaBuilder cb, Root<TA001> root) {
        final List<Predicate> predicates = new ArrayList<Predicate>();

        if (dateStart != null ) {
            ParameterExpression<Date> param = cb.parameter(Date.class, "dateStart");
            predicates.add(cb.greaterThanOrEqualTo(root.<Date>get("gateway_time"), param));
        }

        if (dateEnd != null ) {
            ParameterExpression<Date> param = cb.parameter(Date.class, "dateEnd");
            predicates.add(cb.lessThanOrEqualTo(root.<Date>get("gateway_time"), param));
        }

        if (aircraft != null && !aircraft.isEmpty()) {
            predicates.add(cb.like(root.<String>get("aircraft_id"), "%"+aircraft+"%"));
        }

        if (smi != null && !smi.isEmpty()) {
            predicates.add(cb.equal(root.<String>get("smi"), smi));
        }

        if (flight_id != null && !flight_id.isEmpty()) {
            predicates.add(cb.like(root.<String>get("flight_id"), "%"+flight_id+"%"));
        }


        if (contains != null && !contains.isEmpty()) {
            predicates.add(cb.like(root.<String>get("raw_msg"), "%"+contains+"%"));
        }
        return predicates;
    }
}
